<template>
  <div>
    <div class="limit-order">
      <div class="g-form form">
        <div class="head">
          <div class="title">
            <h2>Limit Order</h2>
            <span>The most innovative limit order</span>
          </div>
          <div class="setting">
            <div class="g-clickable" @click="quote">
              <svg
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 19 19"
                id="arrow_loading"
                class="arrow-loading"
              >
                <path
                  stroke="none"
                  fill="var(--color-light)"
                  d="M17.61907,6.64429064 L13.8617197,6.64429064 C13.3840439,6.64429064 12.9914138,6.25155686 12.9914138,5.77398471 C12.9914138,5.2963089 13.3840439,4.90357512 13.8617197,4.90357512 L15.3689095,4.90357512 C14.0103035,2.98248087 11.7707673,1.73006538 9.2340637,1.73006538 C5.0840575,1.73006538 1.7194412,5.09468172 1.7194412,9.24468791 C1.7194412,13.3946681 5.0840575,16.7592845 9.2340637,16.7592845 C13.3840439,16.7592845 16.74866,13.3946681 16.74866,9.24468791 C16.74866,8.76701211 17.141394,8.37438191 17.61907,8.37438191 C18.096616,8.37438191 18.48935,8.76701211 18.48935,9.24468791 C18.48935,14.3498902 14.3498902,18.4893498 9.2446879,18.4893498 C4.139356,18.4893498 0,14.3498902 0,9.24468791 C0,4.13935601 4.139356,0 9.2446879,0 C12.3438798,0 15.0823402,1.52833455 16.759284,3.86343695 L16.759284,2.31382802 C16.759284,1.83615222 17.152018,1.44352209 17.62959,1.44352209 C18.10724,1.44352209 18.5,1.83615222 18.5,2.31382802 L18.5,5.78450529 C18.478726,6.26218109 18.096616,6.64429064 17.61907,6.64429064 Z"
                ></path>
                <defs>
                  <path
                    id="arrow"
                    stroke="none"
                    fill="none"
                    d="M17.61907,6.64429064 L13.8617197,6.64429064 C13.3840439,6.64429064 12.9914138,6.25155686 12.9914138,5.77398471 C12.9914138,5.2963089 13.3840439,4.90357512 13.8617197,4.90357512 L15.3689095,4.90357512 C14.0103035,2.98248087 11.7707673,1.73006538 9.2340637,1.73006538 C5.0840575,1.73006538 1.7194412,5.09468172 1.7194412,9.24468791 C1.7194412,13.3946681 5.0840575,16.7592845 9.2340637,16.7592845 C13.3840439,16.7592845 16.74866,13.3946681 16.74866,9.24468791 C16.74866,8.76701211 17.141394,8.37438191 17.61907,8.37438191 C18.096616,8.37438191 18.48935,8.76701211 18.48935,9.24468791 C18.48935,14.3498902 14.3498902,18.4893498 9.2446879,18.4893498 C4.139356,18.4893498 0,14.3498902 0,9.24468791 C0,4.13935601 4.139356,0 9.2446879,0 C12.3438798,0 15.0823402,1.52833455 16.759284,3.86343695 L16.759284,2.31382802 C16.759284,1.83615222 17.152018,1.44352209 17.62959,1.44352209 C18.10724,1.44352209 18.5,1.83615222 18.5,2.31382802 L18.5,5.78450529 C18.478726,6.26218109 18.096616,6.64429064 17.61907,6.64429064 Z"
                  ></path>
                  <clipPath id="arrow-clip">
                    <use xlink:href="#arrow"></use>
                  </clipPath>
                </defs>
                <g clip-path="url(#arrow-clip)">
                  <circle
                    cx="7.02"
                    cy="7.02"
                    r="4.69"
                    transform="rotate(365,12,12)"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="16"
                    stroke-dasharray="30"
                    stroke-dashoffset="0"
                  >
                    <animate
                      attributeName="stroke-dashoffset"
                      values="0;-30"
                      begin="arrow_loading.click; 0.7s"
                      repeatCount="indefinite"
                      dur="9.3s"
                    ></animate>
                  </circle>
                </g>
                <use xlink:href="#arrow"></use>
                <animateTransform
                  id="transform_0"
                  attributeName="transform"
                  attributeType="XML"
                  type="rotate"
                  from="0 0 0"
                  to="-10 0 0"
                  dur="0.07s"
                  begin="arrow_loading.click;"
                  repeatCount="1"
                ></animateTransform>
                <animateTransform
                  id="transform_1"
                  attributeName="transform"
                  attributeType="XML"
                  type="rotate"
                  from="-45 0 0"
                  to="390 0 0"
                  dur="0.6s"
                  begin="transform_0.end"
                  repeatCount="1"
                ></animateTransform>
                <animateTransform
                  id="transform_2"
                  attributeName="transform"
                  attributeType="XML"
                  type="rotate"
                  from="390 0 0"
                  to="360 0 0"
                  dur="0.15s"
                  begin="transform_1.end"
                  repeatCount="1"
                ></animateTransform>
              </svg>
            </div>
            <div class="g-clickable" @click="isShowOrderHistory = true">
              <i class="iconfont icon-history"></i>
            </div>
            <div class="g-clickable" @click="isShowSetting = true">
              <i class="iconfont icon-setting"></i>
            </div>
          </div>
        </div>
        <SwapField
          v-model="inAmount"
          type="from"
          :token="from"
          @select="showSelectToken"
        />
        <div class="mid">
          <div class="switch">
            <div class="g-clickable icon" @click="change">
              <i class="iconfont icon-switch"></i>
            </div>
          </div>
          <OrderExpire v-model="orderExpire" />
          <OrderPrice :quote-price="quotePrice" @change="changePrice" />
        </div>
        <SwapField
          v-model="outAmount"
          type="to"
          :token="to"
          @select="showSelectToken"
        />
        <SwapLabel name="Price" class="mt20" :value="price" />
        <SwapLabel name="Slippage tolerance" :value="`${tolerance}%`" />
        <SwapButton :amount="inAmount" @confirm="confirm" />
        <div v-if="showMore">
          <SwapLabel
            name="Maximum Sold"
            class="mt20"
            help="1"
            value="10 USDT"
          />
          <SwapLabel
            name="Price Impact"
            help="1"
            value="< 0.01%"
            :blue="true"
          />
          <SwapLabel name="Liquidity Provider Fee" help="1" value="0.03 USDT" />
          <SwapLabel name="Route" help="1">
            <div class="route">
              <img src="@/assets/token/icon-usdt.svg" />
              <span>USDT</span>
              <i class="iconfont icon-arrow-down2"></i>
              <img src="@/assets/token/icon-usdc.svg" />
              <span>USDC</span>
              <i class="iconfont icon-arrow-down2"></i>
              <img src="@/assets/token/icon-dai.svg" />
              <span>DAI</span>
            </div>
          </SwapLabel>
        </div>
      </div>
    </div>
    <NouDialog close-on-click-modal :visible.sync="isShowConfirm">
      <SwapConfirm
        :in-amount="inAmount"
        :out-amount="outAmount"
        :min-out-amount="minOutAmount"
        @close="isShowConfirm = false"
        @confirm="confirmSwap"
      />
    </NouDialog>
    <NouDialog close-on-click-modal :visible.sync="isShowSetting">
      <SwapSetting @close="isShowSetting = false" />
    </NouDialog>
    <NouDialog close-on-click-modal :visible.sync="isShowToken">
      <SwapToken @close="isShowToken = false" @select="hideSelectToken" />
    </NouDialog>
    <BlurMask close-on-click-modal :visible.sync="isShowOrderHistory">
      <OrderHistory @close="isShowOrderHistory = false" />
    </BlurMask>
  </div>
</template>

<script>
import SwapField from "@/components/SwapField";
import SwapLabel from "@/components/SwapLabel";
import SwapButton from "@/components/SwapButton";
import SwapConfirm from "@/components/SwapConfirm";
import SwapSetting from "@/components/SwapSetting";
import SwapToken from "@/components/SwapToken";
import BlurMask from "@/components/common/BlurMask";
import NouDialog from "@/components/common/NouDialog";
import OrderExpire from "./components/OrderExpire";
import OrderPrice from "./components/OrderPrice";
import OrderHistory from "./components/OrderHistory";

import store from "@/store";
import { mapState } from "vuex";
import { getBalanceOf, createLimitOrder } from "@/init";
import { quote, swapQuote } from "@/api/core";
import { decimals2Amount } from "@/utils/number";
import { isNativeToken, proxyContract } from "@/config/config";
import * as BN from "bignumber.js";
import { toFixed } from "@/utils/format";

export default {
  components: {
    SwapField,
    SwapLabel,
    SwapButton,
    SwapConfirm,
    SwapSetting,
    SwapToken,
    NouDialog,
    OrderExpire,
    OrderPrice,
    BlurMask,
    OrderHistory,
  },
  computed: {
    ...mapState({
      from: (state) => state.from,
      to: (state) => state.to,
      account: (state) => state.account,
      tolerance: (state) => state.tolerance,
      showMore: (state) => state.showMore,
    }),
    price() {
      if (this.outAmount && this.inAmount) {
        const amount = this.outAmount / this.inAmount;
        return `${amount} ${this.to.symbol} Per ${this.from.symbol}`;
      }
      return "--";
    },
  },
  data() {
    return {
      isSelectType: "from",
      isShowConfirm: false,
      isShowSetting: false,
      isShowToken: false,
      isShowOrderHistory: false,
      inAmount: "0",
      outAmount: "0",
      minOutAmount: "0",
      timeout: null,
      orderPrice: "",
      quotePrice: "",
      orderExpire: "3D",
    };
  },
  watch: {
    "from.address"() {
      this.quotePrice = "";
      this.orderPrice = "";
      this.inAmount = 1;
      this.quote();
      getBalanceOf("from");
    },
    "to.address"() {
      this.quotePrice = "";
      this.orderPrice = "";
      this.quote();
      getBalanceOf("to");
    },
    account() {
      this.getBalance();
    },
    inAmount() {
      this.quote();
    },
    orderPrice(newVal, oldVal) {
      this.outAmount = toFixed(BN(newVal).multipliedBy(this.inAmount), 6);
    },
    quotePrice(newVal, oldVal) {
      if (!this.orderPrice) {
        this.outAmount = toFixed(BN(newVal).multipliedBy(this.inAmount), 6);
      }
    },
  },
  mounted() {
    this.inAmount = "1";
    this.getBalance();
  },
  methods: {
    async getBalance() {
      await getBalanceOf("from");
      await getBalanceOf("to");
    },
    change() {
      store.commit("SET_SWITCH");
    },
    quote() {
      clearTimeout(this.timeout);
      this.timeout = setTimeout(() => {
        this.doQuote();
      }, this.timeout);
    },
    changePrice(price) {
      this.orderPrice = price;
    },
    async doQuote() {
      const amount = this.inAmount;
      const res = await quote("bsc", {
        inTokenAddress: this.from.address,
        outTokenAddress: this.to.address,
        amount,
      });
      const { outAmountNum } = res || {};
      this.outAmount = outAmountNum;
      this.quotePrice = outAmountNum > 0 ? outAmountNum / amount : 0;
    },
    hideSelectToken(token) {
      if (this.isSelectType === "from") {
        store.commit("SET_FROM", token);
      } else {
        store.commit("SET_TO", token);
      }
      this.isShowToken = false;
    },
    showSelectToken(type) {
      this.isSelectType = type;
      this.isShowToken = true;
    },
    async confirm() {
      this.isShowConfirm = true;
    },
    async confirmSwap() {
      this.isShowConfirm = false;
      await createLimitOrder({
        from: this.from,
        to: this.to,
        amount: this.inAmount,
        tolerance: this.tolerance,
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.form {
  &.ext {
    padding-top: 16px;
    margin-top: 20px;
  }

  .head {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .title {
      display: flex;
      flex-direction: column;
      h2 {
        font-size: 18px;
        line-height: 1;
        font-family: "Roboto Bold";
        color: var(--color);
        margin-bottom: 15px;
      }

      span {
        font-size: 15px;
        line-height: 1;
        font-family: "Roboto Regular";
        color: var(--color-content);
      }
    }

    .setting {
      display: flex;
      align-items: center;

      div {
        width: 36px;
        height: 36px;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      i {
        font-size: 30px;
        color: var(--color-content);
      }

      .arrow-loading {
        width: 18px;
      }
    }
  }

  .mid {
    margin: 5px 0 -15px;
    display: grid;
    align-items: center;
    grid-template-columns: 60px 135px 1fr;
    .switch {
      height: 42px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-top: 28px;

      div {
        cursor: pointer;
        width: 42px;
        height: 42px;

        display: flex;
        align-items: center;
        justify-content: center;
      }

      i {
        font-size: 32px;
        color: var(--color);
      }
    }
  }

  .route {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    margin-right: -10px;

    img {
      width: 21px;
      border-radius: 12px;
      margin-right: 6px;
    }

    span {
      font-size: 14px;
      line-height: 1;
      font-family: "Roboto Medium";
      margin-right: 15px;
    }

    i {
      font-size: 18px;
      transform: rotate(-90deg);
      margin-right: 10px;
    }
  }
}
</style>
